Counting Bits
LeetCode 338 | Difficulty: Easyβ
EasyProblem Descriptionβ
Given an integer n, return an array ans of length n + 1 such that for each i* *(`0 0
1 --> 1
2 --> 10
**Example 2:**
Input: n = 5 Output: [0,1,1,2,1,2] Explanation: 0 --> 0 1 --> 1 2 --> 10 3 --> 11 4 --> 100 5 --> 101
**Constraints:**
- `0 <= n <= 10^5`
**Follow up:**
- It is very easy to come up with a solution with a runtime of `O(n log n)`. Can you do it in linear time `O(n)` and possibly in a single pass?
- Can you do it without using any built-in function (i.e., like `__builtin_popcount` in C++)?
**Topics:** `Dynamic Programming`, `Bit Manipulation`
---
## Approach
### Dynamic Programming
Break the problem into overlapping subproblems. Define a **state** (what information do you need?), a **recurrence** (how does state[i] depend on smaller states?), and a **base case**. Consider both top-down (memoization) and bottom-up (tabulation) approaches.
:::tip When to use
Optimal substructure + overlapping subproblems (counting ways, min/max cost, feasibility).
:::
### Bit Manipulation
Operate directly on binary representations. Key operations: AND (&), OR (|), XOR (^), NOT (~), shifts (<<, >>). XOR is especially useful: a ^ a = 0, a ^ 0 = a.
:::tip When to use
Finding unique elements, power of 2 checks, subset generation, toggling flags.
:::
---
## Solutions
### Solution 1: C# (Best: 125 ms)
| Metric | Value |
|--------|-------|
| **Runtime** | 125 ms |
| **Memory** | 38.3 MB |
| **Date** | 2022-03-01 |
```csharp title="Solution"
public class Solution {
public int[] CountBits(int n) {
int[] f = new int[n + 1];
for (int i=1; i<=n; i++) f[i] = f[i >> 1] + (i & 1);
return f;
}
}
Complexity Analysisβ
| Approach | Time | Space |
|---|---|---|
| Dynamic Programming | $O(n)$ | $O(n)$ |
| Bit Manipulation | $O(n) or O(1)$ | $O(1)$ |
Interview Tipsβ
Key Points
- Start by clarifying edge cases: empty input, single element, all duplicates.
- Define the DP state clearly. Ask: "What is the minimum information I need to make a decision at each step?"
- Consider if you can reduce space by only keeping the last row/few values.
- LeetCode provides 3 hint(s) for this problem β try solving without them first.
π‘ Hints
Hint 1: You should make use of what you have produced already.
Hint 2: Divide the numbers in ranges like [2-3], [4-7], [8-15] and so on. And try to generate new range from previous.
Hint 3: Or does the odd/even status of the number help you in calculating the number of 1s?